package com.ruoyi.web.controller.front;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.page.FrontPage;
import com.ruoyi.common.enums.FrontMenuEnum;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.TArticle;
import com.ruoyi.system.domain.TCompanyInfo;
import com.ruoyi.system.domain.TFrontMenu;
import com.ruoyi.system.domain.TMessage;
import com.ruoyi.system.service.ITArticleService;
import com.ruoyi.system.service.ITCompanyInfoService;
import com.ruoyi.system.service.ITFrontMenuService;
import com.ruoyi.system.service.ITMessageService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.lang.model.type.IntersectionType;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @Author: likailun
 * @Description:
 * @Date: create in 2024/4/17 19:58
 */

@Controller
@RequestMapping("/front")
public class FrontController extends BaseController {
    private final static String prefix = "front";

    @Value("${system.name}")
    private String systemName;
    @Autowired
    private ITFrontMenuService tFrontMenuService;
    @Resource
    private ITArticleService articleService;
    @Resource
    private ITCompanyInfoService companyInfoService;
    @Resource
    private ITMessageService messageService;

    @GetMapping("/{categorize}")
    public String path(@PathVariable("categorize") String categorize, String category, ModelMap mmap,
                       @RequestParam(value = "pageSize",required = false) Integer pageSize,
                       @RequestParam(value = "pageNum",required = false) Integer pageNum) {
        AtomicReference<String> active = new AtomicReference<>("/front/index");
        final TCompanyInfo companyInfo = this.getCompanyInfo();
        StringBuilder title = new StringBuilder(StringUtils.isEmpty(companyInfo.getCompanyName()) ? systemName : companyInfo.getCompanyName());
        TFrontMenu condition = new TFrontMenu();
        condition.setIsDisplay(1L);
        List<TFrontMenu> tFrontMenus = tFrontMenuService.selectTFrontMenuList(condition);
        List<TFrontMenu> menus = new ArrayList<>();
        AtomicReference<String> activeChild = new AtomicReference<>("");
        if (CollectionUtils.isNotEmpty(tFrontMenus)) {
            for (TFrontMenu tFrontMenu : tFrontMenus) {
                if (tFrontMenu.getPageUrl().startsWith("/front/" + categorize)) {
                    active.set("/front/" + categorize);
                    title.append("|").append(tFrontMenu.getMenuName());
                    if (StringUtils.isNotEmpty(category) && tFrontMenu.getPageUrl().equals("/front/" + categorize + "?category" + "=" + category)) {
                        activeChild.set(tFrontMenu.getPageUrl());
                    }
                }
            }
            tFrontMenus.stream().filter(t -> t.getParentId() == 0L).forEach(t -> {
                List<TFrontMenu> collect = tFrontMenus.stream().filter(c -> c.getParentId().equals(t.getId())).peek(c -> c.setRootUrl(c.getPageUrl().split("\\?")[0])).collect(Collectors.toList());
                t.setChilds(collect);
                t.setRootUrl(t.getPageUrl().split("\\?")[0]);
                t.setActive(t.getRootUrl().equals("/front/" + categorize) ? 1 : 0);
                if (StringUtils.isEmpty(activeChild.get()) && t.getActive() == 1 && CollectionUtils.isNotEmpty(collect)) {
                    activeChild.set(collect.get(0).getPageUrl());
                }
                menus.add(t);
            });
        }
        mmap.put("activeChild", activeChild.get());
        mmap.put("systemName", systemName);
        mmap.put("title", title.toString());
        mmap.put("activeParent", active.get());
        mmap.put("menus", menus);
        mmap.put("company", companyInfo);
        if (CollectionUtils.isNotEmpty(tFrontMenus)) {
            Optional<TFrontMenu> menu = Optional.empty();
            if (StringUtils.isNotEmpty(activeChild.get())) {
                // 选中子菜单
                menu = tFrontMenus.stream().filter(m -> m.getPageUrl().equals(activeChild.get())).findAny();
            } else if (StringUtils.isNotEmpty(active.get())) {
                menu = tFrontMenus.stream().filter(m -> m.getPageUrl().equals(active.get())).findAny();
            }
            if (menu.isPresent()) {
                mmap.put("url", menu.get().getPageUrl());
                this.queryFrontData(categorize, menu.get(), menus, mmap,pageSize,pageNum);
            }
        }
        return prefix + "/" + categorize;
    }

    @GetMapping("/articleView/{id}")
    public String articleView(@PathVariable("id") Long id, ModelMap mmap) {
        TArticle article = articleService.selectTArticleById(id);
        if (Objects.isNull(article)) {
            // 查不到数据，直接去首页了
            return "redirect:/front/index";
        }
        AtomicReference<String> active = new AtomicReference<>("/front/index");
        final TCompanyInfo companyInfo = this.getCompanyInfo();
        StringBuilder title = new StringBuilder(StringUtils.isEmpty(companyInfo.getCompanyName()) ? systemName : companyInfo.getCompanyName());
        TFrontMenu condition = new TFrontMenu();
        condition.setIsDisplay(1L);
        List<TFrontMenu> allMenus = tFrontMenuService.selectTFrontMenuList(condition);
        List<TFrontMenu> menus = new ArrayList<>();
        AtomicReference<String> activeChild = new AtomicReference<>("");
        Optional<TFrontMenu> menu = Optional.empty();
        if (CollectionUtils.isNotEmpty(allMenus)) {
            menu = allMenus.stream().filter(m -> m.getId().equals(article.getFrontMenuId())).findAny();
            List<TFrontMenu> parents = new ArrayList<>();
            if (menu.isPresent()) {
                this.parents(menu.get(), allMenus, parents);
                mmap.put("current", menu.get());
                title.append("|").append(menu.get().getMenuName());
                activeChild.set(menu.get().getPageUrl());
                mmap.put("parent", parents);
                Optional<TFrontMenu> finalMenu = menu;
                allMenus.stream().filter(t -> t.getParentId() == 0L).forEach(t -> {
                    List<TFrontMenu> collect = allMenus.stream().filter(c -> c.getParentId().equals(t.getId())).peek(c -> c.setRootUrl(c.getPageUrl().split("\\?")[0])).collect(Collectors.toList());
                    t.setChilds(collect);
                    t.setRootUrl(t.getPageUrl().split("\\?")[0]);
                    t.setActive(t.getRootUrl().equals(finalMenu.get().getPageUrl().split("\\?")[0]) ? 1 : 0);
                    menus.add(t);
                });
            }
        }
        if (menu.isPresent()) {
            final Map<String, Long> stringLongMap = articleService.queryPrevAndNext(id, menu.get().getId());
            final long prevId = MapUtils.getLongValue(stringLongMap, "prev_id", 0L);
            if (prevId > 0) {
                // 上一篇
                mmap.put("prev", articleService.selectTArticleById(prevId));
            }
            final long nextId = MapUtils.getLongValue(stringLongMap, "next_id", 0L);
            if (nextId > 0) {
                // 上一篇
                mmap.put("next", articleService.selectTArticleById(nextId));
            }
        }
        final TArticle tArticle = new TArticle();
        tArticle.setId(id);
        tArticle.setViewCount(Objects.isNull(article.getViewCount()) ? 1 : article.getViewCount() + 1);
        articleService.updateTArticle(tArticle);
        article.setViewCount(tArticle.getViewCount());
        mmap.put("article", article);
        mmap.put("activeChild", activeChild.get());
        mmap.put("systemName", systemName);
        mmap.put("title", title.toString());
        mmap.put("activeParent", active.get());
        mmap.put("menus", menus);
        mmap.put("company", companyInfo);
        return prefix + "/articleView";
    }


    @PostMapping("/contact/submit")
    public String saveMessage(TMessage message,ModelMap mmap){
        message.setCreateTime(new Date());
        message.setHandlingStatus(0);
        messageService.insertTMessage(message);

        AtomicReference<String> active = new AtomicReference<>("/front/index");
        final TCompanyInfo companyInfo = this.getCompanyInfo();
        StringBuilder title = new StringBuilder(StringUtils.isEmpty(companyInfo.getCompanyName()) ? systemName : companyInfo.getCompanyName());
        TFrontMenu condition = new TFrontMenu();
        condition.setIsDisplay(1L);
        List<TFrontMenu> allMenus = tFrontMenuService.selectTFrontMenuList(condition);
        List<TFrontMenu> menus = new ArrayList<>();
        AtomicReference<String> activeChild = new AtomicReference<>("");
        Optional<TFrontMenu> menu = Optional.empty();
        if (CollectionUtils.isNotEmpty(allMenus)) {
            menu = allMenus.stream().filter(m -> m.getMenuName().equals("联系我们")).findAny();
            if (menu.isPresent()) {
                mmap.put("current", menu.get());
                title.append("|").append(menu.get().getMenuName());
                activeChild.set(menu.get().getPageUrl());
                Optional<TFrontMenu> finalMenu = menu;
                allMenus.stream().filter(t -> t.getParentId() == 0L).forEach(t -> {
                    List<TFrontMenu> collect = allMenus.stream().filter(c -> c.getParentId().equals(t.getId())).peek(c -> c.setRootUrl(c.getPageUrl().split("\\?")[0])).collect(Collectors.toList());
                    t.setChilds(collect);
                    t.setRootUrl(t.getPageUrl().split("\\?")[0]);
                    t.setActive(t.getRootUrl().equals(finalMenu.get().getPageUrl().split("\\?")[0]) ? 1 : 0);
                    menus.add(t);
                });
            }
        }
        mmap.put("activeChild", activeChild.get());
        mmap.put("systemName", systemName);
        mmap.put("title", title.toString());
        mmap.put("activeParent", active.get());
        mmap.put("menus", menus);
        mmap.put("company", companyInfo);
        return prefix+"/contact-sucess";
    }

    /**
     * ajax 查询明细
     * @return
     */
    @GetMapping(value = "/teamDetail/{id}")
    @ResponseBody
    public ResponseEntity<TArticle> getTeamDetail(@PathVariable("id")Long id){
        TArticle article = articleService.selectTArticleById(id);
        return ResponseEntity.ok(article);
    }


    private void parents(TFrontMenu current, List<TFrontMenu> tFrontMenus, List<TFrontMenu> parents) {
        parents.add(current);
        final Optional<TFrontMenu> parent = tFrontMenus.stream().filter(m -> m.getId().equals(current.getParentId())).findFirst();
        if (parent.isPresent()) {
            if (parent.get().getParentId() > 0) {
                this.parents(parent.get(), tFrontMenus, parents);
            } else {
                parents.add(0, parent.get());
            }
        }

    }

    private void queryFrontData(String categorize, TFrontMenu menu, List<TFrontMenu> menus, ModelMap mmap,Integer pageSize,Integer pageNum) {
        FrontMenuEnum menuEnum = FrontMenuEnum.getByCategorize(categorize);
        if (Objects.isNull(menuEnum)) {
            return;
        }
        switch (menuEnum) {
            case INDEX:
                // 产品中心
                mmap.put("products", getIndexPageArticle(menus, "产品中心", 1, 4));
                // 产品中心
                mmap.put("business", getIndexPageArticle(menus, "业务中心", 1, 4));
                mmap.put("news", getIndexPageArticle(menus, "新闻中心", 1, 8));
                final List<TArticle> about = getIndexPageArticle(menus, "关于我们", 1, 1);
                mmap.put("about", CollectionUtils.isNotEmpty(about)?about.get(0):new TArticle());
                mmap.put("team", getIndexPageArticle(menus, "团队中心", 1, 8));
                break;
            case BUSINESS:
            case PRODUCT:
            case NEWS:
            case TEAM:
                if(null==pageSize){
                    pageSize=8;
                }
                if(pageNum==null){
                    pageNum=1;
                }
                startPage(pageNum, pageSize);
                TArticle article = new TArticle();
                article.setFrontMenuId(menu.getId());
                List<TArticle> tArticles = articleService.selectTArticleList(article);
                FrontPage page = getFrontPage(tArticles);
                mmap.put("page", page);
                break;
            case CONTACT:
                break;
            case ABOUT:
                startPage(1, 1);
                TArticle ta = new TArticle();
                ta.setFrontMenuId(menu.getId());
                List<TArticle> tas = articleService.selectTArticleList(ta);
                mmap.put("article", CollectionUtils.isNotEmpty(tas) ? tas.get(0) : null);
                break;
        }
    }

    /**
     * 查询首页部分的文章
     *
     * @param menus
     */
    private List<TArticle> getIndexPageArticle(List<TFrontMenu> menus, String menuName, int pageSize, int pageNumber) {
        List<TArticle> tArticles = new ArrayList<>();
        startPage(pageSize, pageNumber);
        TArticle productCon = new TArticle();
        final Optional<TFrontMenu> productMenu = menus.stream().filter(m -> m.getMenuName().equals(menuName)).findAny();
        if (productMenu.isPresent()) {
            final HashMap<String, Object> params = new HashMap<>();
            params.put("frontMenuIds", new ArrayList<Long>() {{
                add(productMenu.get().getId());
                if (CollectionUtils.isNotEmpty(productMenu.get().getChilds())) {
                    addAll(productMenu.get().getChilds().stream().map(TFrontMenu::getId).collect(Collectors.toSet()));
                }
            }});
            productCon.setParams(params);
            productCon.setIsDisplay(1L);
            tArticles = articleService.selectTArticleList(productCon);
        }
        return tArticles;
    }
    //private

    private TCompanyInfo getCompanyInfo() {
        final List<TCompanyInfo> tCompanyInfos = companyInfoService.selectTCompanyInfoList(new TCompanyInfo());
        return CollectionUtils.isNotEmpty(tCompanyInfos) ? tCompanyInfos.get(0) : new TCompanyInfo();
    }
}
